﻿using K8.LSF;
using Rougamo;
using Rougamo.Context;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunWMS.SpiService.Services;

internal class OperationLogAttribute : MoAttribute
{
    private string operationName;
    private long? userId;
    private string userName;
    private string clientIp;
    private string inParam = "";
    private string groupId;
    private long Id = 10000000;//共享Id
    private bool InsertRes = false;//进入方法记录是否插入成功标志
    public OperationLogAttribute(string operationName)
    {
        this.operationName = operationName;
        this.groupId = DateTime.Now.ToString("yyyyMMdd HHmmssff");
    }

    /// <summary>
    /// 方法执行前切入执行
    /// </summary>
    /// <param name="context"></param>
    public override void OnEntry(MethodContext context)
    {
        try
        {
            int j = 0;
            for (int i = context.Arguments.Length - 1; i >= 0; i--)
            {
                if (context.Arguments.Length >= 4)//参数列表已经按照格式【例：(参数类 param, long userId, string userName, string clientHost)】更改的部分
                {
                    if (j == 0)
                    {
                        clientIp = context.Arguments[i].ToJson();
                        j++;
                    }
                    else if (j == 1)
                    {
                        userName = context.Arguments[i].ToJson();
                        j++;
                    }
                    else if (j == 2)
                    {
                        userId = context.Arguments[i] != null ? Convert.ToInt64(context.Arguments[i]) : null;
                        j++;
                    }
                    else
                    {
                        inParam = inParam + context.Arguments[i].ToJson();
                    }
                }
                else
                {
                    inParam = inParam + context.Arguments[i].ToJson();
                    j = -1;
                }

            }

            var db = Db.Default;
            // 设置主键
            var max = db.LogOperations.Select(s => s.Id).Max();
            if (max != null && max > 0) Id = Convert.ToInt64(max) + 1;

            #region 向数据库添加数据
            var result = -1;
            if (j == -1)//接口未按照指定格式填写
            {
                result = db.LogOperations.Insert(new POLogOperation
                {
                    Id = Id,
                    OperationName = operationName,
                    OperationStatus = "开始",
                    InParams = inParam.Replace("\\", ""),
                    OutParams = context.ReturnValue.ToJson(),
                    GroupId = groupId,
                    IsDetail = true,
                    Remark = $"{operationName}开始执行",
                    RemarkMemo = "接口中，用户Id、用户名、IP未设置"
                });
            }
            else
            {
                result = db.LogOperations.Insert(new POLogOperation
                {
                    Id = Id,
                    OperationName = operationName,
                    OperationStatus = "开始",
                    InParams = inParam.Replace("\\", ""),
                    OutParams = context.ReturnValue.ToJson(),
                    GroupId = groupId,
                    IsDetail = true,
                    Clientip = clientIp,
                    UserId = userId,
                    UserName = userName,
                    Remark = $"{operationName}开始执行",
                });
            }
            if (result > 0) InsertRes = true;//插入结果

            #endregion


        }
        catch (Exception e)
        {
            Client.Log(new Log { Data = $"类型：{context.Method.DeclaringType.Name}-方法：{context.Method.Name}-参数：{context.Arguments.ToJson()},--异常：{e.ToString()} " });
            throw;
        }


    }

    /// <summary>
    /// 方法执行完成后切入执行
    /// </summary>
    /// <param name="context"></param>
    public override void OnExit(MethodContext context)
    {
        if (InsertRes)//进入方法时，插入成功后，可修改
        {
            try
            {
                var db = Db.Default;
                var result = db.LogOperations.Where(f => f.Id == Id).Update( new POLogOperation
                {
                    OutParams = context.ReturnValue.ToJson(),
                    OperationStatus = "完成",
                    UpdateTime = DateTime.Now,
                    Remark = $"{operationName}执行完成"
                });
            }
            catch (Exception e)
            {
                Client.Log(new Log { Data = $"类型：{context.Method.DeclaringType.Name}-方法：{context.Method.Name}-参数：{context.Arguments.ToJson()},--异常：{e.ToString()} " });
                throw;
            }

        }

    }

    public override void OnException(MethodContext context)
    {

        var db = Db.Default;

        if (InsertRes)//进入方法记录插入成功，修改状态
        {
            var result = db.LogOperations.Where(f => f.Id == Id).Update( new POLogOperation
            {
                Remark = $"指令异常：{context.Exception.Message}",
                OperationStatus = "异常",
                UpdateTime = DateTime.Now
            });
        }
        else//未成功，添加异常记录
        {
            var result = db.LogOperations.Insert(new POLogOperation
            {
                Id = Id,
                OperationName = operationName,
                OperationStatus = "异常",
                InParams = inParam.Replace("\\", ""),
                OutParams = context.ReturnValue.ToJson(),
                GroupId = groupId,
                IsDetail = true,
                Clientip = clientIp,
                UserId = userId,
                UserName = userName,
                Remark = $"指令异常：{context.Exception.Message}",
            });
        }

        base.OnException(context);
    }

    /// <summary>
    /// 方法执行成功时切入执行
    /// </summary>
    /// <param name="context"></param>
    public override void OnSuccess(MethodContext context)
    {
        if (InsertRes)//进入方法时，插入成功后，可修改
        {
            try
            {
                var db = Db.Default;
                var result = db.LogOperations.Where(f => f.Id == Id).Update( new POLogOperation
                {
                    OperationStatus = "成功",
                    UpdateTime = DateTime.Now
                });
            }
            catch (Exception e)
            {
                Client.Log(new Log { Data = $"类型：{context.Method.DeclaringType.Name}-方法：{context.Method.Name}-参数：{context.Arguments.ToJson()},--异常：{e.ToString()} " });
                throw;
            }

        }
    }
}
